package com.culture.config.service.impl;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.culture.config.common.util.ExceptionUtil;
import com.culture.config.dao.entity.User;
import com.culture.config.dao.entity.UserAction;
import com.culture.config.dao.entity.UserMenu;
import com.culture.config.dao.entity.UserRole;
import com.culture.config.dao.mapper.UserActionMapper;
import com.culture.config.dao.mapper.UserMapper;
import com.culture.config.dao.mapper.UserMenuMapper;
import com.culture.config.dao.mapper.UserRoleMapper;
import com.culture.config.model.AuthInfo;
import com.culture.config.model.MenuInfo;
import com.culture.config.model.ServiceInfo;
import com.culture.config.service.AuthService;
import com.culture.config.util.AuthenticationUtil;
import com.culture.config.wrapper.AuthWrapper;
import com.culture.config.wrapper.MenuWrapper;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class AuthServiceImpl implements AuthService{	
	@Resource
	private UserMapper userMapper;
	@Resource
	private UserRoleMapper userRoleMapper;
	@Resource
	private UserActionMapper userActionMapper;
	@Resource
	private UserMenuMapper userMenuMapper;

	@Value("${spring.config.admin.app.host}")
	private String appHost;
	@Value("${spring.config.admin.api.base}")
	private String apiBase;

	@Override
	public List<User> listAll() {
		List<User> userList = this.userMapper.listAll(new User());
		if(CollectionUtils.isEmpty(userList)) {
			return Collections.emptyList();
		}
		return userList;
	}

	@Override
	public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
		log.info("loadUserByUsername:{}",userName);		
		User u = this.userMapper.getByName(new User(userName));
		if(Objects.isNull(u)) {
			log.warn("loadUserByUsername is null with:{}",userName);
			return null;
		}		
		List<UserRole> userRoleList = this.userRoleMapper.listByUserId(new UserRole(u.getId()));
		List<UserAction> userRoleActionList = this.userActionMapper.listByUserId(new UserAction(u.getId()));
		return AuthWrapper.wrapUserDetails(u,userRoleList,userRoleActionList);
	}

	@Override
	public User getCurrentUser() {
		String authUserName = AuthenticationUtil.getCurrentUserName();
		User u = this.userMapper.getByName(new User(authUserName));
		if(Objects.isNull(u)) {
			log.warn("getCurrentUser:{} not exists.",authUserName);
			return null;
		}	
		return u;
	}

	@Override
	public AuthInfo getAuthInfo() {		
		User user = this.getCurrentUser();
		ExceptionUtil.businessExceptionWhenNull(user,"Not Allowed!");
		ExceptionUtil.businessExceptionWhenTrue(!user.getEnable(), "Forbid!");
		List<UserRole> userRoleList = this.userRoleMapper.listByUserId(new UserRole(user.getId()));	
		return AuthWrapper.wrapAuthInfo(user,userRoleList);
	}

	@Override
	public MenuInfo getMenuInfo() {
		User user = this.getCurrentUser();
		ExceptionUtil.businessExceptionWhenNull(user,"Not Allowed!");
		ExceptionUtil.businessExceptionWhenTrue(!user.getEnable(), "Forbid!");
		List<UserMenu> userMenuList = this.userMenuMapper.listByUserId(new UserMenu(user.getId()));
		return MenuWrapper.wrapMenuInfo(user,userMenuList);
	}

	@Override
	public ServiceInfo getServiceInfo() {		
		return new ServiceInfo(appHost,apiBase);
	}	
}
